package com.network.retrofit_rx.download;

import android.support.annotation.NonNull;
import android.util.Log;

import com.network.utils.RxBus;
import com.network.utils.RxUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;


/**
 * 文件下载回调
 * Created by QiQi on 2017/8/23.
 */

public abstract class FileCallback implements Callback<ResponseBody>, IFileLoadCallback {

    public final static String TAG = FileCallback.class.getName();

    //订阅下载进度
    private Disposable disposable;

    /**
     * 目标文件存储的文件夹路劲
     */
    private String destFileDir;

    /**
     * 目标文件存储的文件名
     */
    private String destFileName;

    public FileCallback(String destFileDir, String destFileName) {
        this.destFileDir = destFileDir;
        this.destFileName = destFileName;
        subscribeLoadProgress();//订阅下载进度
    }


    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        try {
            saveFile(response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        onFailure(t);
    }

    /**
     * 通过IO流写入文件
     *
     * @param response
     * @throws Exception
     */
    public void saveFile(Response<ResponseBody> response) throws Exception {
        InputStream in = null;
        FileOutputStream out = null;

        byte[] buf = new byte[2048];

        int len;

        try {
            File dir = new File(destFileDir);
            if (!dir.exists()) {
                if (!dir.mkdirs()) {
                    Log.i(TAG, "saveFile: create dirs failure");
                    return;
                }
            }

            in = response.body().byteStream();
            File file = new File(dir, destFileName);
            out = new FileOutputStream(file);
            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
            }

            onSuccess(file);
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
            unSubscribe();
        }
    }

    /**
     * 订阅文件下载进度
     */
    private void subscribeLoadProgress() {
        disposable = RxBus.getDefault().toFlowable(FileLoadBean.class)
                .onBackpressureBuffer()
                .compose(RxUtil.getRxSchedulerHelper())
                .subscribe(new Consumer<FileLoadBean>() {
                    @Override
                    public void accept(@NonNull FileLoadBean fileLoadBean) throws Exception {
                        onProgress(fileLoadBean.getBytesRead(), fileLoadBean.getContentLength());
                    }
                });
    }

    private void unSubscribe() {
        if (!disposable.isDisposed()) {
            disposable.dispose();
        }
    }
}

